﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ParieurPro.DAL;
using ParieurPro.DAL.DatabaseModel;

namespace MyBet.Web.Controls
{
    public partial class Bet : System.Web.UI.UserControl
    {
        public enum EventStatus { NotStarted, Bet, Finished } ;
        public Guid debugUser=new Guid("{FF10E3C2-DB21-4360-8576-81B3E54888D6}");
        public bool overwriteUser = true;

        /// <summary>
        /// Return current day to bet or in pending of results
        /// </summary>
        /// <returns></returns>
        private int GetCurrentDay(List<EventObject> events)
        {
            var query = from entry in events
              where (entry.OpenDate < DateTime.UtcNow)
              orderby entry.CloseDate descending
              select entry;
            IList<EventObject> championshipdays = query.ToList();
            if (championshipdays.Count < 1)
            {

                // First day ?
                EventObject firstEvent = (from entry in events
                                          where DateTime.UtcNow < entry.OpenDate
                                          orderby entry.OpenDate
                                          select entry).FirstOrDefault();
                if (firstEvent != null)
                {
                    return firstEvent.DayNumber;
                }

                // No more day to bet
                // Return last one
                var queryLastone = from entry in events
                            orderby entry.CloseDate descending
                            select entry;
                IList<EventObject> lastDays = queryLastone.ToList();
                if (lastDays.Count < 1)
                {
                    throw new Exception("No days in this championship"); 
                }
                return lastDays[0].DayNumber;
            }
            return championshipdays[0].DayNumber;
        }

        /// <summary>
        /// Renvoi le statut d'une journée de championnat
        /// - Non commencé
        /// - Pari ouvert
        /// - Pari clos
        /// </summary>
        /// <param name="currentEvent"></param>
        /// <returns></returns>
        public static EventStatus GetStatus(EventObject currentEvent)
        {
            //#if DEBUG
            //return EventStatus.NotStarted;
            //#else
            // case 1 : Finished : Bet is closed
            if (currentEvent.CloseDate < DateTime.UtcNow)
            {
                return EventStatus.Finished;
            }
            // case 2 : Bets are opened
            if ((currentEvent.OpenDate < DateTime.UtcNow) && (currentEvent.CloseDate > DateTime.UtcNow))
            {
                return EventStatus.Bet;
            }
            // case 3 : Not started
            return EventStatus.NotStarted;
            //#endif

        }

        protected void Page_Load(object sender, EventArgs e)
        {
            int currentEventId;
            int currentDayNumber;
   
            if (!IsPostBack)
            {
                if (Session["CurrentUser"] == null)
                {
                    return;
                }

                using (MyBetDBEntities dbContext = new MyBetDBEntities())
                {
                    UserObject user = Session["CurrentUser"] as UserObject;
                    List<EventObject> events = EventObject.GetEventsFromCustomContest(dbContext, user.CustomContestId);
                    Dictionary<int, EventObject> eventDictionary;

//#if DEBUG
//                    if (overwriteUser)
//                    {
//                        user.UserId = debugUser;
//                    }
//#endif

                    // Récupération de la journée en cours
                    try
                    {
                        currentDayNumber = GetCurrentDay(events);
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Trace.WriteLine(ex.ToString());
                        return;
                    }

                    if (Session["Events"] == null)
                    {
                        Session["Events"] = new Dictionary<int, EventObject>();
                    }

                    eventDictionary = Session["Events"] as Dictionary<int, EventObject>;
                    eventDictionary.Clear();

                    // Remplissage de la liste des journées
                    foreach (EventObject item in events)
                    {
                        ListItem currentItem = new ListItem(String.Format("Journée {0}", item.DayNumber), item.EventId.ToString());
                        EventList.Items.Add(currentItem);
                        if (item.DayNumber == currentDayNumber)
                        {
                            EventList.SelectedValue = currentItem.Value;
                        }
                        // Mémorisation de l'événement
                        eventDictionary.Add(item.EventId, item);
                    }

                    currentEventId = Convert.ToInt32(EventList.SelectedValue);
                    UpdateMatchList(currentEventId);
                }
                
            }
            
        }

        /// <summary>
        /// Mise à jour de la liste des matchs
        /// </summary>
        /// <param name="eventId">Evenement courant</param>
        protected void UpdateMatchList(int eventId)
        {
            Dictionary<int, EventObject> eventDictionary;
            UserObject user = Session["CurrentUser"] as UserObject;
            eventDictionary = Session["Events"] as Dictionary<int, EventObject>;

            //#if DEBUG
            //if (overwriteUser)
            //{
            //    user.UserId = debugUser;
            //}
            //#endif

            if (eventDictionary != null)
            {

                using (MyBetDBEntities dbContext = new MyBetDBEntities())
                {
                    EventObject currentEvent = eventDictionary[eventId];
                    EventStatus currentStatus = GetStatus(currentEvent);
                    Match.MatchMode currentMode = Match.MatchMode.Readonly;
                    List<MatchObject> matchs = MatchObject.GetMatchsFromEvent(dbContext, eventId);
                    Dictionary<int, UserBets> betDictionary = BetObject.GetBetsDictionaryInDatabase(dbContext, user.UserId, eventId);
                    RankObject eventScore = RankObject.GetUserRankInDatabaseFromEvent(dbContext, user.CustomContestId, user.UserId, eventId);
                    Dictionary<int, string> teamsDictionary = Session["TeamsDictionary"] as Dictionary<int, string>;
                    EventDate.Text = String.Format("Fermeture le {0} à {1}",currentEvent.CloseDate.ToLocalTime().ToShortDateString(),currentEvent.CloseDate.ToLocalTime().ToShortTimeString());

                    if ((eventScore!=null) && (eventScore.LastBetUpdate.HasValue))
                    {
                        EventBetDate.Text = String.Format("Pari enregistré le {0} à {1}", eventScore.LastBetUpdate.Value.ToLocalTime().ToShortDateString(), eventScore.LastBetUpdate.Value.ToLocalTime().ToShortTimeString());
                    }
                    else
                    {
                        EventBetDate.Text = String.Empty;
                    }

                    switch (currentStatus)
                    {
                        case EventStatus.NotStarted:
                            currentMode = Match.MatchMode.Edit;
                            BetButton.Visible = true;
                            MatchReadonly.Visible = false;
                            MatchEdit.Visible = true;
                            break;
                        case EventStatus.Bet:
                            currentMode = Match.MatchMode.Edit;
                            BetButton.Visible = true;
                            MatchReadonly.Visible = false;
                            MatchEdit.Visible = true;
                            break;
                        case EventStatus.Finished:
                            currentMode = Match.MatchMode.Readonly;
                            BetButton.Visible = false;
                            MatchReadonly.Visible = true;
                            MatchEdit.Visible = false;
                            break;
                        default:
                            currentMode = Match.MatchMode.Readonly;
                            BetButton.Visible = false;
                            MatchEdit.Visible = false;
                            break;
                    }

                    int currentMatch = 1;
                    foreach (MatchObject match in matchs)
                    {
                        //Match matchControl = (Match)LoadControl("~/Controls/Match.ascx");
                        //matchControl.SetMatch(match, currentMode);
                        //MatchPlaceHolder.Controls.Add(matchControl);
                        //DropDownList list = new DropDownList();
                        //list.Items.Add(new ListItem("", "-1"));
                        //for (int i = 0; i < 10; i++)
                        //{
                        //    list.Items.Add(new ListItem(i.ToString(), i.ToString()));
                        //}
                        //MatchPlaceHolder.Controls.Add(list);
                        if (currentMode == Match.MatchMode.Readonly)
                        {
                            DisplayReadOnlyMatch(betDictionary, teamsDictionary, currentMatch, match);
                        }
                        else
                        {
                            DisplayEditMatch(betDictionary, teamsDictionary, currentMatch, match);

                        }
                        currentMatch++;
                    }
                }
            }
        }

        public enum PredictionType
        {
            HomeWin, DrawGame, AwayWin
        }

        private PredictionType GetPredictionType(int scoreHome, int scoreAway)
        {
            if (scoreHome > scoreAway)
            {
                return PredictionType.HomeWin;
            }
            else if (scoreAway > scoreHome)
            {
                return PredictionType.AwayWin;
            }
            else
            {
                return PredictionType.DrawGame;
            }
        }

        private bool IsGoodPrediction(MatchObject CurrentMatch, int scoreHome, int scoreAway)
        {
            if ((CurrentMatch.TeamHomeScore.HasValue) && (CurrentMatch.TeamAwayScore.HasValue))
            {
                if (GetPredictionType(scoreHome, scoreAway) == GetPredictionType(CurrentMatch.TeamHomeScore.Value, CurrentMatch.TeamAwayScore.Value))
                {
                    return true;
                }
            }
            return false;
        }

        private void DisplayEditMatch(Dictionary<int, UserBets> betDictionary, Dictionary<int, string> teamsDictionary, int currentMatch, MatchObject match)
        {
            Label HomeTeamLabel = FindControl(String.Format("Match{0}HomeTeamEdit", currentMatch)) as Label;
            Label AwayTeamLabel = FindControl(String.Format("Match{0}AwayTeamEdit", currentMatch)) as Label;
            DropDownList HomeScoreDDL = FindControl(String.Format("Match{0}HomeScoreEdit", currentMatch)) as DropDownList;
            DropDownList AwayScoreDDL = FindControl(String.Format("Match{0}AwayScoreEdit", currentMatch)) as DropDownList;
            HiddenField MatchId = FindControl(String.Format("Match{0}Id", currentMatch)) as HiddenField;

            if (match.DisplayName == "1")
            {
                HomeTeamLabel.ForeColor = System.Drawing.Color.Red;
                AwayTeamLabel.ForeColor = System.Drawing.Color.Red;
            }
            else
            {
                HomeTeamLabel.ForeColor = System.Drawing.Color.Black;
                AwayTeamLabel.ForeColor = System.Drawing.Color.Black;
            }

            MatchId.Value = match.MatchId.ToString();
            if (HomeTeamLabel != null)
            {
                HomeTeamLabel.Text = teamsDictionary[match.TeamHomeId];
            }
            if (AwayTeamLabel != null)
            {
                AwayTeamLabel.Text = teamsDictionary[match.TeamAwayId];
            }
            if ((HomeScoreDDL != null) && (AwayScoreDDL != null))
            {
                if (betDictionary.ContainsKey(match.MatchId))
                {
                    HomeScoreDDL.SelectedValue = betDictionary[match.MatchId].ScoreHome.ToString();
                    AwayScoreDDL.SelectedValue = betDictionary[match.MatchId].ScoreAway.ToString();
                }
                else
                {
                    HomeScoreDDL.SelectedValue = "-1";
                    AwayScoreDDL.SelectedValue = "-1";
                }
            }
        }

        private void DisplayReadOnlyMatch(Dictionary<int, UserBets> betDictionary, Dictionary<int, string> teamsDictionary, int currentMatch, MatchObject match)
        {
            Label HomeTeamLabel = FindControl(String.Format("Match{0}HomeTeamReadOnly", currentMatch)) as Label;
            Label AwayTeamLabel = FindControl(String.Format("Match{0}AwayTeamReadOnly", currentMatch)) as Label;
            Label HomeScoreLabel = FindControl(String.Format("Match{0}HomeScoreReadOnly", currentMatch)) as Label;
            Label AwayScoreLabel = FindControl(String.Format("Match{0}AwayScoreReadOnly", currentMatch)) as Label;
            Label BetReadOnlyLabel = FindControl(String.Format("Match{0}BetReadOnly", currentMatch)) as Label;


            if (match.DisplayName == "1")
            {
                HomeTeamLabel.ForeColor = System.Drawing.Color.Red;
                AwayTeamLabel.ForeColor = System.Drawing.Color.Red;
            }
            else
            {
                HomeTeamLabel.ForeColor = System.Drawing.Color.Black;
                AwayTeamLabel.ForeColor = System.Drawing.Color.Black;
            }

            if (HomeTeamLabel != null)
            {
                HomeTeamLabel.Text = teamsDictionary[match.TeamHomeId];
            }
            if (AwayTeamLabel != null)
            {
                AwayTeamLabel.Text = teamsDictionary[match.TeamAwayId];
            }
            if (HomeScoreLabel != null)
            {
                if (match.TeamHomeScore.HasValue)
                {
                    HomeScoreLabel.Text = match.TeamHomeScore.Value.ToString();
                }
                else
                {
                    HomeScoreLabel.Text = "?";
                }
            }
            if (AwayScoreLabel != null)
            {
                if (match.TeamAwayScore.HasValue)
                {
                    AwayScoreLabel.Text = match.TeamAwayScore.Value.ToString();
                }
                else
                {
                    AwayScoreLabel.Text = "?";
                }
            }
            if ((match.TeamHomeScore.HasValue) && (match.TeamAwayScore.HasValue))
            {
                if (match.TeamHomeScore.Value > match.TeamAwayScore.Value)
                {
                    HomeTeamLabel.Font.Bold = true;
                }
                else if (match.TeamHomeScore.Value < match.TeamAwayScore.Value)
                {
                    AwayTeamLabel.Font.Bold = true;
                }
                
                BetReadOnlyLabel.ForeColor = System.Drawing.Color.Black;
                if (betDictionary.ContainsKey(match.MatchId))
                {
                    if (IsGoodPrediction(match, betDictionary[match.MatchId].ScoreHome, betDictionary[match.MatchId].ScoreAway))
                    {
                        if ((match.TeamHomeScore.Value==betDictionary[match.MatchId].ScoreHome) && (match.TeamAwayScore.Value==betDictionary[match.MatchId].ScoreAway))
                        {
                            BetReadOnlyLabel.ForeColor=System.Drawing.Color.Green;
                        }
                        else
                        {
                            BetReadOnlyLabel.ForeColor=System.Drawing.Color.Orange;
                        }
                    }
                }

            }

            if (BetReadOnlyLabel != null)
            {
                if (betDictionary.ContainsKey(match.MatchId))
                {
                    BetReadOnlyLabel.Text = betDictionary[match.MatchId].ScoreHome.ToString() + " - " + betDictionary[match.MatchId].ScoreAway.ToString();
                }
                else
                {
                    BetReadOnlyLabel.Text = "";
                }
            }
        }

        protected void EventList_SelectedIndexChanged(object sender, EventArgs e)
        {
                int currentEventId=Convert.ToInt32(EventList.SelectedValue);
                ErrorMessage.Visible = false;
                UpdateMatchList(currentEventId);
        }

        /// <summary>
        /// Click sur le bouton parier
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void BetButton_Click(object sender, EventArgs e)
        {
            List<int> matchId = new List<int>();
            List<int> scoreHome = new List<int>();
            List<int> scoreAway = new List<int>();
            UserObject currentUser = Session["CurrentUser"] as UserObject;
            int currentEventId = Convert.ToInt32(EventList.SelectedValue);

            //#if DEBUG
            //if (overwriteUser)
            //{
            //    currentUser.UserId = debugUser;
            //}
            //#endif

            ErrorMessage.ForeColor = System.Drawing.Color.Red;

            if (Match1HomeScoreEdit.SelectedValue == "-1" || Match1AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }
            if (Match2HomeScoreEdit.SelectedValue == "-1" || Match2AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }
            if (Match3HomeScoreEdit.SelectedValue == "-1" || Match3AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }
            if (Match4HomeScoreEdit.SelectedValue == "-1" || Match4AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }
            if (Match5HomeScoreEdit.SelectedValue == "-1" || Match5AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }
            if (Match6HomeScoreEdit.SelectedValue == "-1" || Match6AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }
            if (Match7HomeScoreEdit.SelectedValue == "-1" || Match7AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }
            if (Match8HomeScoreEdit.SelectedValue == "-1" || Match8AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }
            if (Match9HomeScoreEdit.SelectedValue == "-1" || Match9AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }
            if (Match10HomeScoreEdit.SelectedValue == "-1" || Match10AwayScoreEdit.SelectedValue == "-1")
            {
                ErrorMessage.Text = "Veuillez parier sur tous les matchs";
                ErrorMessage.Visible = true;
                return;
            }

            // Construction de la liste des Ids
            matchId.Add(Convert.ToInt32(Match1Id.Value));
            matchId.Add(Convert.ToInt32(Match2Id.Value));
            matchId.Add(Convert.ToInt32(Match3Id.Value));
            matchId.Add(Convert.ToInt32(Match4Id.Value));
            matchId.Add(Convert.ToInt32(Match5Id.Value));
            matchId.Add(Convert.ToInt32(Match6Id.Value));
            matchId.Add(Convert.ToInt32(Match7Id.Value));
            matchId.Add(Convert.ToInt32(Match8Id.Value));
            matchId.Add(Convert.ToInt32(Match9Id.Value));
            matchId.Add(Convert.ToInt32(Match10Id.Value));

            // Construction de la liste des scores
            scoreHome.Add(Convert.ToInt32(Match1HomeScoreEdit.SelectedValue));
            scoreHome.Add(Convert.ToInt32(Match2HomeScoreEdit.SelectedValue));
            scoreHome.Add(Convert.ToInt32(Match3HomeScoreEdit.SelectedValue));
            scoreHome.Add(Convert.ToInt32(Match4HomeScoreEdit.SelectedValue));
            scoreHome.Add(Convert.ToInt32(Match5HomeScoreEdit.SelectedValue));
            scoreHome.Add(Convert.ToInt32(Match6HomeScoreEdit.SelectedValue));
            scoreHome.Add(Convert.ToInt32(Match7HomeScoreEdit.SelectedValue));
            scoreHome.Add(Convert.ToInt32(Match8HomeScoreEdit.SelectedValue));
            scoreHome.Add(Convert.ToInt32(Match9HomeScoreEdit.SelectedValue));
            scoreHome.Add(Convert.ToInt32(Match10HomeScoreEdit.SelectedValue));

            scoreAway.Add(Convert.ToInt32(Match1AwayScoreEdit.SelectedValue));
            scoreAway.Add(Convert.ToInt32(Match2AwayScoreEdit.SelectedValue));
            scoreAway.Add(Convert.ToInt32(Match3AwayScoreEdit.SelectedValue));
            scoreAway.Add(Convert.ToInt32(Match4AwayScoreEdit.SelectedValue));
            scoreAway.Add(Convert.ToInt32(Match5AwayScoreEdit.SelectedValue));
            scoreAway.Add(Convert.ToInt32(Match6AwayScoreEdit.SelectedValue));
            scoreAway.Add(Convert.ToInt32(Match7AwayScoreEdit.SelectedValue));
            scoreAway.Add(Convert.ToInt32(Match8AwayScoreEdit.SelectedValue));
            scoreAway.Add(Convert.ToInt32(Match9AwayScoreEdit.SelectedValue));
            scoreAway.Add(Convert.ToInt32(Match10AwayScoreEdit.SelectedValue));
            using (MyBetDBEntities dbContext = new MyBetDBEntities())
            {
                try
                {
                    switch (BetObject.SetPrediction(dbContext, currentUser.UserId, currentEventId, matchId, scoreHome, scoreAway, DateTime.UtcNow))
                    {
                        case BetObject.PredictionValidationStatus.Success:
                            ErrorMessage.ForeColor = System.Drawing.Color.Green;
                            ErrorMessage.Text = "Paris enregistrés !";
                            break;
                        case BetObject.PredictionValidationStatus.DateExpired:
                            ErrorMessage.ForeColor = System.Drawing.Color.Red;
                            ErrorMessage.Text = "Les paris sont clos, impossible de mettre à jour les paris !";
                            break;
                        default:
                            ErrorMessage.ForeColor = System.Drawing.Color.Red;
                            ErrorMessage.Text = "Erreur lors de la mise à jour des paris, veuillez réessayer ultérieurement.";
                            break;
                    }

                    List<MatchInfo> matchInfo = new List<MatchInfo>();
                    matchInfo = MatchObject.GetMatchsInfos(dbContext, matchId);
                    BetObject.SendBetSummary(currentUser.Email, EventList.SelectedItem.ToString(), matchInfo, scoreHome, scoreAway);
                }
                catch (Exception ex)
                {
                    ErrorMessage.ForeColor = System.Drawing.Color.Red;
                    ErrorMessage.Text = String.Format("Erreur lors de la mise à jour des paris, veuillez réessayer ultérieurement ({0})",ex.Message);                         
                }
            }
            ErrorMessage.Visible = true;
        }


    }
}